package dms.repository.impl;
/**
 * @author 李健
 */
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import dms.model.School;
import dms.model.role.Student;
import dms.model.util.FindUtil;
import dms.model.util.PageIterator;
import dms.repository.StudentRepository;
import dms.util.HibernateUtil;

public class StudentRepositoryHibernate implements StudentRepository {

	private static Log log = LogFactory.getLog(SchoolRepositoryHibernate.class);
	
	@Override
	public Student createStudent(Student studentInfo) {
		Session session = null;
		Transaction tx = null;
		 
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			session.save(studentInfo);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return studentInfo;
	}

	@Override
	public void deleteById(Long id) {
		Session session = null;
		Transaction tx = null;
		Student s = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			s = (Student) session.load(Student.class, id);
			session.delete(s);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
	}

	@Override
	public PageIterator<Student> findAll(int start, int count) {
		Session session = null;
		Transaction tx = null;
		PageIterator<Student> iter = null;
		List<Student> list = null;
		Long allCount = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			String countQuery = "select count(*) from Student ";
			String findQuery = "select s from Student ";
			
			allCount = FindUtil.calculateAllCount(session, countQuery, null);
			list = FindUtil.getEntitiesByPage(session, findQuery, null, start, count);
			iter = new PageIterator<Student>(list, allCount, start, count);
				
			tx.commit();
			
		} catch (Exception e) {
			log.error(e.toString());
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		
		return iter;
	}

	@Override
	public Student findById(Long id) {
		Session session = null;
		Transaction tx = null;
		Student s = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			s = (Student) session.load(Student.class, id);
			//initialize property
			Hibernate.initialize(s);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return s;
	}

	@Override
	public PageIterator<Student> findByQuery(int start, int count, String queryStr) {
		Session session = null;
		Transaction tx = null;
		Student s = null;
		List<Student> students = null;
		Long allCount = null;
		PageIterator<Student> iter = null;
		
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			Query query = session.createQuery("select s from Student s where s.account.name like :query or " +
											  "s.dormitory.name like :query or s.classes.name like :query " +
											  "or s.school.name like :query or s.faculty.name like :query ")
											  .setString("query", "%" + queryStr + "%")
											  .setFirstResult(0)
											  .setMaxResults(count);
			allCount = (Long) session.createQuery("select count(*) from Student s where s.account.name like :query or " +
										   "s.dormitory.name like :query or s.classes.name like :query " +
										   "or s.school.name like :query or s.faculty.name like :query ")
										   .setParameter("query", queryStr)
										   .uniqueResult();
			
				
			students = query.list();
			iter = new PageIterator<Student>(students, allCount, start, count);
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return iter;
	}

	@Override
	public Student updateStudent(Student studentInfo) {
		Session session = null;
		Transaction tx = null;
		Student s = null;
		 
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			tx = session.beginTransaction();
			
			s = (Student) session.merge(studentInfo);
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return s;
	}

	

}
